home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / vga_card.000 / vga_cardgames-1.3.1.tar / vga_cardgames / ohlinux.c < prev    next >
C/C++ Source or Header  |  1995-02-26  |  13KB  |  601 lines

  1. /*
  2.  * Oh Hell!
  3.  *
  4.  * Copyright (C) Evan Harris, 1991, 1993, 1994, 1995.
  5.  *
  6.  * Permission is granted to freely redistribute and modify this code,
  7.  * providing the author(s) get credit for having written it.
  8.  */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12.  
  13. #include <vga.h>
  14. #include <vgamouse.h>
  15.  
  16. #include "vga16.h"
  17. #include "mouse.h"
  18. #include "key.h"
  19. #include "ohhell.h"
  20.  
  21.  
  22. #define OH_SCREENMODE G640x480x16
  23. #define OH_SCREENWIDTH 640
  24. #define OH_SCREENHEIGHT 480
  25.  
  26. #define OH_TEXTFG 1
  27. #define OH_TEXTBG 0
  28. #define OH_BUTTONFG 2
  29. #define OH_BUTTONBG 6
  30. #define OH_MOUSEFG 5
  31. #define OH_MOUSEDARKFG 2
  32.  
  33. #define NUMCARDIMAGES 52
  34. #define CARDACTUALWIDTH 53
  35. #define CARDIMAGEWIDTH 56
  36. #define CARDIMAGEHEIGHT 80
  37.  
  38. #define VERSION "OH HELL!  v1.3"
  39.  
  40. #ifndef CARDSFILE
  41. #define CARDSFILE "Cards56x80"
  42. #endif
  43. #ifndef CARDSMOUSESAMPLERATE
  44. #define CARDSMOUSESAMPLERATE MOUSE_DEFAULTSAMPLERATE
  45. #endif
  46.  
  47. #define USLEEP_TIME 30000
  48.  
  49.  
  50. #define CARDTOIMAGE(card)    (card % NUMCARDIMAGES)
  51.  
  52. #define BITWIDTH CARDIMAGEWIDTH /* multiple of 8 */
  53. #define BITHEIGHT CARDIMAGEHEIGHT
  54. #define BITSHOWLEFT 24        /* multiple of 8 */
  55.  
  56. #define OH_QUITLEFT (OH_SCREENWIDTH - 88)
  57. #define OH_QUITRIGHT (OH_QUITLEFT + 80)
  58. #define OH_QUITBOTTOM 76
  59. #define OH_QUITTOP (OH_QUITBOTTOM - 16)
  60. #define OH_NEWGAMEBOTTOM 48
  61. #define OH_NEWGAMETOP (OH_NEWGAMEBOTTOM - 16)
  62.  
  63. #define OH_PALETTESIZE 9
  64.  
  65. int palette[OH_PALETTESIZE * 3] = {
  66.     0x00, 0x20, 0x00,        /* green */
  67.     0x3f, 0x3f, 0x3f,        /* white */
  68.     0x00, 0x00, 0x00,        /* black */
  69.     0x37, 0x00, 0x00,        /* red */
  70.     0x00, 0x00, 0x20,        /* blue */
  71.     0x3f, 0x3f, 0x00,        /* yellow */
  72.     0x1a, 0x1a, 0x1a,        /* grey */
  73. };
  74.  
  75. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  76. static void LoadCards(char *file);
  77. static long GetMouseButton(void);
  78. static void WhileMouseButton(void);
  79.  
  80. static unsigned char ***imageCard;
  81. static unsigned char *blankLine;
  82.  
  83.  
  84. void
  85. InitDisplay(int argc, char **argv)
  86. {
  87.     vga_disabledriverreport();
  88.     vga_init();
  89. #if !defined(CARDSMOUSE)
  90.     vga_setmousesupport(1);
  91. #endif
  92.     
  93.     if (vga_setmode(OH_SCREENMODE) != 0) {
  94.     fprintf(stderr, "Mode %s not available!\n",
  95.         vga_getmodename(OH_SCREENMODE));
  96.     exit(1);
  97.     }
  98.  
  99. #if defined(CARDSMOUSE)
  100.     mouse_init("/dev/mouse", vga_getmousetype(), CARDSMOUSESAMPLERATE);
  101.     mouse_setxrange(0, OH_SCREENWIDTH - 1);
  102.     mouse_setyrange(0, OH_SCREENHEIGHT - 1);
  103.     mouse_setwrap(MOUSE_NOWRAP);
  104. #endif
  105.  
  106.     vga16_init();
  107.  
  108.     LoadCards(CARDSFILE);
  109.  
  110.     blankLine = (unsigned char *)calloc(OH_SCREENWIDTH, sizeof(unsigned char));
  111.     if (blankLine == NULL) {
  112.     fprintf(stderr, "Error: cannot get memory for blankLine\n");
  113.     exit(1);
  114.     }
  115.  
  116.     vga_setpalvec(0, OH_PALETTESIZE, &palette[0]);
  117.  
  118.     vga16_text(16, OH_SCREENHEIGHT - 56, "SCORES", OH_TEXTFG, OH_TEXTBG);
  119.     vga16_text(OH_SCREENWIDTH - 110, OH_SCREENHEIGHT - 56, "BIDS",
  120.            OH_TEXTFG, OH_TEXTBG);
  121.     vga16_text(OH_SCREENWIDTH - 52, OH_SCREENHEIGHT - 56, "TRICKS",
  122.            OH_TEXTFG, OH_TEXTBG);
  123.  
  124.     vga16_text(OH_QUITLEFT, OH_QUITBOTTOM, "   QUIT   ",
  125.            OH_BUTTONFG, OH_BUTTONBG);
  126.     vga16_text(OH_QUITLEFT, OH_NEWGAMEBOTTOM, " NEW GAME ",
  127.            OH_BUTTONFG, OH_BUTTONBG);
  128.  
  129.     vga16_text(OH_SCREENWIDTH - 120, 120, VERSION, OH_TEXTFG, OH_TEXTBG);
  130. }
  131.  
  132.  
  133. static void
  134. LoadCards(char *file)
  135. {
  136.     int i, j, k, l, c, colour;
  137.     FILE *f;
  138.  
  139.     f = fopen(file, "r");
  140.     if (f == NULL) {
  141.     fprintf(stderr, "Cannot find '%s'\n", file);
  142.     exit(1);
  143.     }
  144.  
  145.     imageCard = (unsigned char ***)malloc(NUMCARDIMAGES
  146.                       * sizeof(unsigned char **));
  147.     if (imageCard == NULL) {
  148.     fprintf(stderr, "Error: cannot get memory for imageCard\n");
  149.     exit(1);
  150.     }
  151.     for (i = 0; i < NUMCARDIMAGES; i++) {
  152.     imageCard[i] = (unsigned char **)malloc(CARDIMAGEHEIGHT
  153.                         * sizeof(unsigned char *));
  154.     if (imageCard == NULL) {
  155.         fprintf(stderr, "Error: cannot get memory for imageCard[%d]\n",
  156.             i);
  157.         exit(1);
  158.     }
  159.     for (j = 0; j < CARDIMAGEHEIGHT; j++) {
  160.         imageCard[i][j] = (unsigned char *)malloc(CARDIMAGEWIDTH
  161.                               * sizeof(unsigned char));
  162.         if (imageCard[i][j] == NULL) { 
  163.         fprintf(stderr,
  164.             "Error: cannot get memory for imageCard[%d][%d]\n",
  165.             i, j);
  166.         exit(1);
  167.         }
  168.         
  169.         if (SUIT(i) == SPADES || SUIT(i) == CLUBS) {
  170.         colour = 2;
  171.         } else {
  172.         colour = 3;
  173.         }
  174.         if (TYPE(i) < JACK) {
  175.         for (k = 0; k < CARDIMAGEWIDTH / 8; k++) {
  176.             if ((c = getc(f)) == EOF) {
  177.             fprintf(stderr, "Unexpected EOF in '%s'\n", file);
  178.             exit(1);
  179.             }
  180.             for (l = 0; l < 8; l++) {
  181.             imageCard[i][j][8 * k + l] =
  182.                 (c & 1 << (7 - l)) ? colour : 1;
  183.             }
  184.         }
  185.         for (k = CARDACTUALWIDTH; k < CARDIMAGEWIDTH; k++) {
  186.             imageCard[i][j][k] = 0;
  187.         }
  188.         } else {
  189.         for (k = 0; k < CARDIMAGEWIDTH / 2; k++) {
  190.             if ((c = getc(f)) == EOF) {
  191.             fprintf(stderr, "Unexpected EOF in '%s'\n", file);
  192.             exit(1);
  193.             }
  194.             imageCard[i][j][2 * k] = (unsigned char)c >> 4;
  195.             imageCard[i][j][2 * k + 1] = (unsigned char)c & 0xf;
  196.         }
  197.         }
  198.     }
  199.     }
  200.  
  201.     fclose(f);
  202. }
  203.  
  204.  
  205. static int cardPosLeft[4] = {    /* S, W, N, E */
  206.     ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~(0x7),
  207.     ((OH_SCREENWIDTH - BITWIDTH) / 8) & ~(0x7),
  208.     ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~(0x7),
  209.     (7 * (OH_SCREENWIDTH - BITWIDTH) / 8) & ~(0x7),
  210. };
  211. static int cardPosTop[4] = {    /* S, W, N, E */
  212.     OH_SCREENHEIGHT - 2 * BITHEIGHT - 10,
  213.     (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2,
  214.     0,
  215.     (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2,
  216. };
  217.  
  218. void
  219. ShowPlay(unsigned char card, unsigned char player)
  220. {
  221.     int line;
  222.     
  223.     for (line = 0; line < BITHEIGHT; line++) {
  224.     vga16_drawscansegment(imageCard[CARDTOIMAGE(card)][line],
  225.                   cardPosLeft[player], cardPosTop[player] + line,
  226.                   BITWIDTH);
  227.     }
  228. }
  229.  
  230.  
  231. void
  232. RemovePlays()
  233. {
  234.     int player, line;
  235.     
  236.     for (player = 0; player < 4; player++) {
  237.     for (line = 0; line < BITHEIGHT; line++) {
  238.         vga16_drawscansegment(blankLine, cardPosLeft[player],
  239.                   cardPosTop[player] + line, BITWIDTH);
  240.     }
  241.     }
  242. }
  243.  
  244.  
  245. static int numInDeal;
  246.  
  247.  
  248. void
  249. ShowHand(unsigned char *hand, unsigned char num)
  250. {
  251.     int left, top, width, line, i;
  252.  
  253.     numInDeal = num;
  254.  
  255.     left = ((OH_SCREENWIDTH - ((num - 1) * BITSHOWLEFT + BITWIDTH)) / 2)
  256.     & ~0x7;
  257.     top = OH_SCREENHEIGHT - BITHEIGHT;
  258.     for (line = 0; line < BITHEIGHT; line++) {
  259.     vga16_drawscansegment(blankLine, left, top + line,
  260.                   BITWIDTH + (num - 1) * BITSHOWLEFT);
  261.     }
  262.  
  263.     left += (num - 1) * BITSHOWLEFT;
  264.     width = BITWIDTH;
  265.     for (i = num - 1; i >= 0; i--) {
  266.     if (hand[i] != NOCARD) {
  267.         for (line = 0; line < BITHEIGHT; line++) {
  268.         vga16_drawscansegment(imageCard[CARDTOIMAGE(hand[i])][line],
  269.                       left, top + line, width);
  270.         }
  271.         width = BITSHOWLEFT;
  272.     } else {
  273.         width += BITSHOWLEFT;
  274.         if (width > BITWIDTH) {
  275.         width = BITWIDTH;
  276.         }
  277.     }
  278.     left -= BITSHOWLEFT;
  279.     }
  280. }
  281.  
  282.  
  283. static int winsPosLeft[4] = {    /* S, W, N, E */
  284.     OH_SCREENWIDTH - 40,
  285.     OH_SCREENWIDTH - 56,
  286.     OH_SCREENWIDTH - 40,
  287.     OH_SCREENWIDTH - 24,
  288. };
  289. static int winsPosTop[4] = {    /* S, W, N, E */
  290.     OH_SCREENHEIGHT - 4,
  291.     OH_SCREENHEIGHT - 20,
  292.     OH_SCREENHEIGHT - 36,
  293.     OH_SCREENHEIGHT - 20,
  294. };
  295.  
  296. void
  297. ShowWins(unsigned char *wins)
  298. {
  299.     char s[4];
  300.     int i;
  301.  
  302.     for (i = 0; i < 4; i++) {
  303.     sprintf(s, "%2d", wins[i]);
  304.     vga16_text(winsPosLeft[i], winsPosTop[i], s, OH_TEXTFG, OH_TEXTBG);
  305.     }
  306. }
  307.  
  308.  
  309. static int bidPosLeft[4] = {    /* S, W, N, E */
  310.     OH_SCREENWIDTH - 106,
  311.     OH_SCREENWIDTH - 122,
  312.     OH_SCREENWIDTH - 106,
  313.     OH_SCREENWIDTH - 90,
  314. };
  315. static int bidPosTop[4] = {    /* S, W, N, E */
  316.     OH_SCREENHEIGHT - 4,
  317.     OH_SCREENHEIGHT - 20,
  318.     OH_SCREENHEIGHT - 36,
  319.     OH_SCREENHEIGHT - 20,
  320. };
  321.  
  322. void
  323. ShowBid(unsigned char bid, unsigned char location)
  324. {
  325.     char s[4];
  326.  
  327.     sprintf(s, "%2d", bid);
  328.     vga16_text(bidPosLeft[location], bidPosTop[location], s,
  329.            OH_TEXTFG, OH_TEXTBG);
  330. }
  331.  
  332.  
  333. void
  334. RemoveBids()
  335. {
  336.     int i;
  337.     
  338.     for (i = 0; i < 4; i++) {
  339.     vga16_text(bidPosLeft[i], bidPosTop[i], "  ", OH_TEXTFG, OH_TEXTBG);
  340.     }
  341. }
  342.  
  343.  
  344. static int scorePosLeft[4] = {    /* S, W, N, E */
  345.     24,
  346.     0,
  347.     24,
  348.     48,
  349. };
  350. static int scorePosTop[4] = {    /* S, W, N, E */
  351.     OH_SCREENHEIGHT - 4,
  352.     OH_SCREENHEIGHT - 20,
  353.     OH_SCREENHEIGHT - 36,
  354.     OH_SCREENHEIGHT - 20,
  355. };
  356.  
  357. void
  358. ShowScores(unsigned char *scores)
  359. {
  360.     int i;
  361.     char s[4];
  362.  
  363.     for (i = 0; i < 4; i++) {
  364.     sprintf(s, "%3d", scores[i]);
  365.     vga16_text(scorePosLeft[i], scorePosTop[i], s, OH_TEXTFG, OH_TEXTBG);
  366.     }
  367. }
  368.  
  369.  
  370. void
  371. ShowTrumps(unsigned char card)
  372. {
  373.     int left, top, line;
  374.  
  375.     left = ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~0x7;
  376.     top = (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2;
  377.  
  378.     for (line = 0; line < BITHEIGHT; line++) {
  379.     vga16_drawscansegment(imageCard[card][line], left, top + line,
  380.                   BITWIDTH);
  381.     }
  382. }
  383.  
  384.  
  385. void
  386. RemoveTrumps()
  387. {
  388.     int left, top, line;
  389.  
  390.     left = ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~0x7;
  391.     top = (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2;
  392.  
  393.     for (line = 0; line < BITHEIGHT; line++) {
  394.     vga16_drawscansegment(blankLine, left, top + line, BITWIDTH);
  395.     }
  396. }
  397.  
  398.  
  399. short
  400. GetPlayerBid(unsigned char max)
  401. {
  402.     char s[6];
  403.     int i, c, left, x, y, len;
  404.     
  405.     vga16_text(10, 20, "Enter bid:", OH_TEXTFG, OH_TEXTBG);
  406.     left = 100;
  407.     for (i = 0; i <= max; i++) {
  408.     sprintf(s, " %d ", i);
  409.     vga16_text(left, 20, s, OH_BUTTONFG, OH_BUTTONBG);
  410.     left += strlen(s) * 8 + 8;
  411.     }
  412.     
  413.     for (c = NOCARD; c == NOCARD;) {
  414.     c = GetMouseButton();
  415.     if (c >= 0) {
  416.         x = (c >> 9);
  417.         y = (c & 0x1ff);
  418.         if (y > 4 && y <= 20) {
  419.         c = 0;
  420.         x -= 100;
  421.         while (x >= 0) {
  422.             len = (c < 10 ? 3 : 4) * 8;
  423.             if (x < len) {
  424.             break;
  425.             }
  426.             c++;
  427.             x -= len + 8;
  428.         }
  429.         if (x < 0 || c > max) {
  430.             c = NOCARD;
  431.         }
  432.         } else {
  433.         c = NOCARD;
  434.         }
  435.     }
  436.     }
  437.  
  438.     WhileMouseButton();
  439.  
  440.     for (i = 0; i < 16; i++) {
  441.     vga16_drawscanline(20 - i, blankLine);
  442.     }
  443.  
  444.     return c;
  445. }
  446.  
  447.  
  448. short
  449. GetCmd()
  450. {
  451.     int c, i, x, y, len;
  452.  
  453.     for (c = NOCARD; c == NOCARD;) {
  454.     c = GetMouseButton();
  455.     if (c >= 0) {
  456.         x = (c >> 9);
  457.         y = (c & 0x1ff);
  458.         if (y >= OH_SCREENHEIGHT - BITHEIGHT && y < OH_SCREENHEIGHT) {
  459.         c = 0;
  460.         x -= (((OH_SCREENWIDTH
  461.             - ((numInDeal - 1) * BITSHOWLEFT + BITWIDTH)) / 2)
  462.               & ~0x7);
  463.         while (x >= 0 && c < numInDeal) {
  464.             if (c == numInDeal - 1) {
  465.             len = BITWIDTH;
  466.             } else {
  467.             len = BITSHOWLEFT;
  468.             i = c + 1;
  469.             while (i < numInDeal && hand[0][i] == NOCARD) {
  470.                 if (i == numInDeal - 1) {
  471.                 len += BITWIDTH;
  472.                 } else {
  473.                 len += BITSHOWLEFT;
  474.                 }
  475.                 i++;
  476.             }
  477.             len = MIN(len, CARDACTUALWIDTH);
  478.             }
  479.             if (x < len && hand[0][c] != NOCARD) {
  480.             break;
  481.             }
  482.             c++;
  483.             x -= BITSHOWLEFT;
  484.         }
  485.         if (x < 0 || c >= numInDeal) {
  486.             c = NOCARD;
  487.         }
  488.         } else {
  489.         c = NOCARD;
  490.         }
  491.     }
  492.     }
  493.  
  494.     WhileMouseButton();
  495.  
  496.     return c;
  497. }
  498.  
  499.  
  500. short
  501. WaitForKey()
  502. {
  503.     long c;
  504.  
  505.     c = GetMouseButton();
  506.     WhileMouseButton();
  507.     if (c < 0) {
  508.     return (short)c;
  509.     } else {
  510.     return CONTINUE;
  511.     }
  512. }
  513.  
  514.  
  515. static int oldx = -1, oldy, oldcolour[40];
  516.  
  517. static long
  518. GetMouseButton()
  519. {
  520.     int x, y, button, key;
  521.  
  522.     x = mouse_getx();
  523.     y = mouse_gety();
  524.     if (x != oldx || y != oldy) {
  525.     if (oldx != -1) {
  526.         RestoreUnderMousePointer(oldx, oldy, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
  527.     }
  528.     SaveUnderMousePointer(x, y, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
  529.     RenderMousePointer(x, y, OH_MOUSEFG, OH_MOUSEDARKFG, OH_SCREENWIDTH, OH_SCREENHEIGHT);
  530.     oldx = x;
  531.     oldy = y;
  532.     }
  533.     
  534.     for (;;) {
  535.     usleep(USLEEP_TIME);    /* don't chew up as much CPU */
  536.  
  537.     if (mouse_update()) {
  538.         x = mouse_getx();
  539.         y = mouse_gety();
  540.         button = mouse_getbutton();
  541.  
  542.         if (x != oldx || y != oldy) {
  543.         if (oldx != -1) {
  544.             RestoreUnderMousePointer(oldx, oldy, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
  545.         }
  546.         SaveUnderMousePointer(x, y, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
  547.         RenderMousePointer(x, y, OH_MOUSEFG, OH_MOUSEDARKFG, OH_SCREENWIDTH, OH_SCREENHEIGHT);
  548.         oldx = x;
  549.         oldy = y;
  550.         }
  551.     
  552.         if (button & MOUSE_LEFTBUTTON) {
  553.         break;
  554.         }
  555.     }
  556.     if ((key = key_getkey()) != -1) {
  557.         switch (key) {
  558.           case 'n':
  559.           case 'N':
  560.         return NEWGAME;
  561.           case 'q':
  562.           case 'Q':
  563.         return QUIT;
  564.           case '\014':
  565.         vga16_redrawscreen();
  566.         break;
  567.           default:
  568.         break;
  569.         }
  570.     }
  571.     }
  572.  
  573.     if (x >= OH_QUITLEFT && x < OH_QUITRIGHT) {
  574.     if (y > OH_NEWGAMETOP && y <= OH_NEWGAMEBOTTOM) {
  575.         return NEWGAME;
  576.     } else if (y > OH_QUITTOP && y <= OH_QUITBOTTOM) {
  577.         return QUIT;
  578.     }
  579.     } 
  580.  
  581.     return (x << 9) | y;
  582. }
  583.  
  584.  
  585. static void
  586. WhileMouseButton()
  587. {
  588.     int button = 1;
  589.     
  590.     while (button) {
  591.     usleep(USLEEP_TIME);    /* don't chew up as much CPU */
  592.  
  593.     mouse_update();
  594.     button = mouse_getbutton();
  595.     }
  596.     if (oldx != -1) {
  597.     RestoreUnderMousePointer(oldx, oldy, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
  598.     }
  599.     oldx = -1;
  600. }
  601.